'use strict';
const ConnectOption = require('../oltmodules/ConnectOption');
const ZTEOLT = require('../oltmodules/ZTEOLT');
const HWOLT = require('../oltmodules/HuaWeiOLT');

const Service = require('egg').Service;
const ulid = require('../public/ulid');
const { option } = require('yargs');
const { rejects } = require('assert');
class Tr069Service extends Service {
  async addConfigTemplate(input) {
    const result = {
      code: '',
      msg: 'config template create success',
      id: '',
    };

    try {
      input.id = ulid.ulid();
      console.log(input);
      await this.ctx.modelmysql.ConfigTemplate.create(input);
      return result;
    } catch (error) {
      console.log(error);
      result.msg = error;
      return result;
    }
  }
  async updateConfigTemplate(input) {
    const result = {
      code: '',
      msg: 'config template update success',
      id: '',
    };

    try {
      await this.ctx.modelmysql.ConfigTemplate.update(input, { where: { id: input.id } });
      return result;
    } catch (error) {
      console.log(error);
      result.msg = error;
      return result;
    }
  }
  async modifyConfigTemplates(input) {
    const result = {
      code: '',
      msg: 'success',
      id: '',
    };
    try {
      const Op = this.ctx.modelmysql.Sequelize.Op;
      if (input.type === 'disable') {
        await this.ctx.modelmysql.ConfigTemplate.update({
          state: false,
        }, {
          where: {
            id: {
              [Op.in]: input.ids,
            },
          },
        });
      } else if (input.type === 'enable') {
        await this.ctx.modelmysql.ConfigTemplate.update({
          state: true,
        }, {
          where: {
            id: {
              [Op.in]: input.ids,
            },
          },
        });
      } else if (input.type === 'delete') {
        await this.ctx.modelmysql.ConfigTemplate.destroy({
          where: {
            id: {
              [Op.in]: input.ids,
            },
          },
        });
      }

      return result;
    } catch (error) {
      console.log(error);
      result.msg = error;
      return result;
    }
  }
  async modifyBusinessTemplates(input) {
    const result = {
      code: '',
      msg: 'success',
      id: '',
    };
    try {
      const Op = this.ctx.modelmysql.Sequelize.Op;
      if (input.type === 'disable') {
        await this.ctx.modelmysql.BusinessTemplate.update({
          state: false,
        }, {
          where: {
            id: {
              [Op.in]: input.ids,
            },
          },
        });
      } else if (input.type === 'enable') {
        await this.ctx.modelmysql.BusinessTemplate.update({
          state: true,
        }, {
          where: {
            id: {
              [Op.in]: input.ids,
            },
          },
        });
      } else if (input.type === 'delete') {
        await this.ctx.modelmysql.BusinessTemplate.destroy({
          where: {
            id: {
              [Op.in]: input.ids,
            },
          },
        });
      }

      return result;
    } catch (error) {
      console.log(error);
      result.msg = error;
      return result;
    }
  }
  async list(tid) {
    try {
      const result = await this.ctx.modelmysql.ConfigTemplate.findAll({
        where: {
          tid,
        },
      });
      return result;
    } catch (error) {
      console.log(error);
      throw error;
    }
  }


  async getBusinessTemplateList(tid) {
    try {
      const result = await this.ctx.modelmysql.BusinessTemplate.findAll({
        where: {
          tid,
        },
      });
      return result;
    } catch (error) {
      console.log(error);
      throw error;
    }
  }
  async getBusinessTemplates(tid) {
    try {
      const result = await this.ctx.modelmysql.BusinessTemplate.findAll({
        where: {
          tid,
          state: 1,
        },
      });
      return result;
    } catch (error) {
      console.log(error);
      throw error;
    }
  }
  async createBusinessTemplate(input) {
    const result = {
      code: '',
      msg: 'success',
      id: '',
    };
    const tid = input.tid;
    input.id = ulid.ulid();
    try {
      await this.ctx.modelmysql.BusinessTemplate.create({
        id: input.id,
        name: input.name,
        configlist: input.configs.toString(),
        memo: input.memo,
        state: input.active,
        content: '',
        tid,
      });
      return result;
    } catch (error) {
      console.log(error);
      result.msg = 'fail';
      return result;
    }
  }
  async updateBusinessTemplate(input) {
    const result = {
      code: '',
      msg: 'success',
      id: '',
    };
    if (input.id === '') {
      result.msg = 'id is null';
      return result;
    }
    try {
      input.state = input.active;
      const res = await this.ctx.modelmysql.BusinessTemplate.update(input, { where: { id: input.id } });
      console.log(res);
      return result;
    } catch (error) {
      console.log(error);
      result.msg = 'fail';
      return result;
    }
  }
  async createDefaultTemplates(input) {
    const result = {
      code: '',
      msg: 'success',
      id: '',
    };
    try {
      const tid = input.tid;
      const list = [];
      const lan = {
        id: ulid.ulid(),
        type: '1',
        name: 'default template-LAN',
        ip: '192.168.1.1',
        dhcp: true,
        dhcpdns: '223.5.5.5,180.76.76.76',
        memo: '192.168.1.1',
        active: true,
      };
      const sip = {
        id: ulid.ulid(),
        type: '6',
        name: 'default template-SIP',
        sip1ServerAddress: '192.168.1.120',
        sip1ServerPort: '5060',
        outboundServerAddress: '192.168.1.120',
        outboundServerPort: '',
        sip2ServerAddress: '192.168.1.120',
        sip2ServerPort: '5060',
        domain: '',
        userInfo: '666 666',
        memo: '',
        active: true,
      };
      const dhcp = {
        id: ulid.ulid(),
        type: '4',
        name: 'default template-WAN DHCP',
        vlanNumber: '201',
        bindPortList: [],
        businesstype: '1',
        memo: '',
        active: true,
      };
      const pppoe = {
        id: ulid.ulid(),
        type: '5',
        name: 'default template-WAN PPPoE',
        vlanNumber: '201',
        bindPortList: [],
        businesstype: '1',
        pppoeusername: 'test',
        pppoepassword: '123456',
        memo: '',
        active: true,
      };
      const fixip = {
        id: ulid.ulid(),
        type: '3',
        name: 'default WAN-FIX-IP',
        vlanNumber: '201',
        bindPortList: [],
        businesstype: '1',
        ip: '100.100.0.123',
        wanSubnetMask: '255.255.255.0',
        wanGatewayIP: '100.100.0.1',
        dns1: '223.5.5.5',
        dns2: '180.76.76.76',
        memo: '',
        active: true,
      };
      const bridge1 = {
        id: ulid.ulid(),
        type: '2',
        name: 'default WAN-BRIDGE-1',
        vlanNumber: '201',
        bindPortList: [ 'LAN 1' ],
        businesstype: '1',
        bridgetype: '1',
        memo: 'bind LAN1',
        active: true,
      };
      const bridge2 = {
        id: ulid.ulid(),
        type: '2',
        name: 'default WAN-BRIDGE-2',
        vlanNumber: '202',
        bindPortList: [ 'LAN 2' ],
        businesstype: '1',
        bridgetype: '1',
        memo: 'bind LAN2',
        active: true,
      };
      list.push({
        id: lan.id,
        name: 'default-LAN',
        type: '1',
        typeName: 'LAN',
        vlanNumber: '',
        memo: '',
        state: true,
        content: JSON.stringify(lan),
        tid,
      });
      list.push({
        id: sip.id,
        name: 'default-SIP',
        type: '6',
        typeName: 'SIP',
        vlanNumber: '',
        memo: '',
        state: true,
        content: JSON.stringify(sip),
        tid,
      });
      list.push({
        id: dhcp.id,
        name: 'default-WAN-DHCP',
        type: '4',
        typeName: 'WAN DHCP',
        vlanNumber: '201',
        memo: '',
        state: true,
        content: JSON.stringify(dhcp),
        tid,
      });
      list.push({
        id: pppoe.id,
        name: 'default-WAN-PPPoE',
        type: '5',
        typeName: 'WAN PPPoE',
        vlanNumber: '201',
        memo: '',
        state: true,
        content: JSON.stringify(pppoe),
        tid,
      });
      list.push({
        id: fixip.id,
        name: 'default-WAN-FIX-IP',
        type: '3',
        typeName: 'WAN fix IP',
        vlanNumber: '201',
        memo: '',
        state: true,
        content: JSON.stringify(fixip),
        tid,
      });
      list.push({
        id: bridge1.id,
        name: 'default-WAN-BRIDGE-1',
        type: '2',
        typeName: 'WAN Bridge',
        vlanNumber: '201',
        memo: '',
        state: true,
        content: JSON.stringify(bridge1),
        tid,
      });
      list.push({
        id: bridge2.id,
        name: 'default-WAN-BRIDGE-2',
        type: '2',
        typeName: 'WAN Bridge',
        vlanNumber: '202',
        memo: '',
        state: true,
        content: JSON.stringify(bridge2),
        tid,
      });
      const list1 = [];
      list1.push({
        id: lan.id,
        name: 'default-LAN',
        type: '1',
        typeName: 'LAN',
        vlanNumber: '',
        memo: '',
        state: true,
        content: JSON.stringify(lan),
        tid,
      });
      list1.push({
        id: sip.id,
        name: 'default-SIP',
        type: '6',
        typeName: 'SIP',
        vlanNumber: '',
        memo: '',
        state: true,
        content: JSON.stringify(sip),
        tid,
      });
      list1.push({
        id: dhcp.id,
        name: 'default-WAN-DHCP',
        type: '4',
        typeName: 'WAN DHCP',
        vlanNumber: '201',
        memo: '',
        state: true,
        content: JSON.stringify(dhcp),
        tid,
      });
      list1.push({
        id: bridge1.id,
        name: 'default-WAN-BRIDGE-1',
        type: '2',
        typeName: 'WAN Bridge',
        vlanNumber: '201',
        memo: '',
        state: true,
        content: JSON.stringify(bridge1),
        tid,
      });
      const dblist = [];
      switch (input.type) {
        case 'config':
          // 默认添加六种配置模板
          for (let i = 0; i < list.length; i++) {
            const item = list[i];
            await this.ctx.modelmysql.ConfigTemplate.findOrCreate({ where: {
              name: item.name,
            }, defaults: item });
          }
          break;
        case 'business':
          // 创建or查询 4个默认配置模板
          for (let i = 0; i < list1.length; i++) {
            const item = list1[i];
            const result = await this.ctx.modelmysql.ConfigTemplate.findOrCreate({ where: {
              name: item.name,
            }, defaults: item });
            dblist.push(result[0].id);
          }

          // 创建默认业务模板
          await this.ctx.modelmysql.BusinessTemplate.findOrCreate({
            where: {
              name: 'default business template',
            }, defaults: {
              id: ulid.ulid(),
              name: 'default business template',
              configlist: dblist.toString(),
              memo: '',
              state: true,
              content: '',
              tid,
            },
          });
          break;
        default:
          break;
      }
      return result;
    } catch (error) {
      console.log(error);
      result.msg = 'fail';
      return result;
    }
  }

  async createGroup(input) {
    const result = {
      code: '',
      msg: 'success',
      id: '',
    };
    const tid = input.tid;
    try {
      await this.ctx.modelmysql.OnuGroup.create({
        id: ulid.ulid(),
        name: input.groupName,
        tid,
      });
      return result;
    } catch (error) {
      result.msg = error;
      return result;
    }
  }

  async getGroups(tid) {
    const result = {
      code: '',
      msg: 'success',
      id: '',
    };
    try {
      const res = await this.ctx.modelmysql.OnuGroup.findAll({ where: {
        tid,
      } });
      return res;
    } catch (error) {
      result.msg = error;
      return result;
    }
  }
  async deleteGroup(input) {
    const result = {
      code: '',
      msg: 'success',
      id: '',
    };
    const id = input.group;
    const tid = input.tid;
    try {

      await this.ctx.modelmysql.OnuGroup.destroy({ where: {
        tid,
        id,
      } });
    } catch (error) {
      result.msg = error;
    }
    return result;
  }
  async addGroup(input) {
    const result = {
      code: '',
      msg: 'success',
      id: '',
    };
    const tid = input.tid;
    try {
      await this.ctx.model.OnuList.updateMany({tid,_id:{$in:input.onus}},{$set:{onugroupId:input.group}})
    } catch (error) {
      result.msg = error;

    }
    return result;
  }
  async subGroup(input) {
    const result = {
      code: '',
      msg: 'success',
      id: '',
    };
    const tid = input.tid;
    try {
      await this.ctx.model.OnuList.updateMany({tid,_id:{$in:input.onus}},{$set:{onugroupId:""}})
    } catch (error) {
      result.msg = error;
    }
    return result;
  }


  async tr069List(params) {
    const tid = params.tid;
    const Op = this.ctx.modelmysql.Sequelize.Op;
    let where = {
      // acsSupport: false,
      acsSupport: true,
      state: 'working',
    };
    if (params.condition) {
      where = {
        [Op.or]: [{ ONUname: { [Op.like]: '%' + params.condition + '%' } },
          { SN: { [Op.like]: '%' + params.condition + '%' } },
        ],

      };
    }
    // if (params.onlineState) {
    //   where.state = params.onlineState;
    // } //由于tr069上只能返回给我在线的onu，所以这里注释掉，上面增加state：‘working’。只查询working状态下的onu列表
    // if (params.configSendState) {
    //   where.configSendState = params.configSendState;
    // }
    if (params.group) {
      where.onugroupid = params.group;
    }
    return await this.ctx.modelmysql.Onu.findAndCountAll({
      where,
      offset: parseInt((params.page - 1) * params.limit),
      limit: parseInt(params.limit),
      order: [[ params.order, params.sort ]],
      include: {
        model: this.ctx.modelmysql.Olt,
        where: {
          tid,
        },
      },
    });
  }
  async sendTemplate(input) {
    const Op = this.ctx.modelmysql.Sequelize.Op;
    const templateInfo = await this.ctx.modelmysql.BusinessTemplate.findOne(
      { where: {
        id: input.templateID,
      } }
    );

    // 查询配置模板信息
    const configListInfo = await this.ctx.modelmysql.ConfigTemplate.findAll({
      where: {
        id: {
          [Op.in]: templateInfo.configlist.split(','),
        },
      },
    });
    return JSON.stringify(configListInfo);
  }

  async updateONUInfos(input) {
    // const Op = this.ctx.modelmysql.Sequelize.Op;
    // const result = await this.ctx.modelmysql.Onu.update({
    //   mac: input.mac,
    //   version: input.hardwareVersion, // 终端型号
    //   manurfactor: input.manurfactor, // 终端厂商
    //   oui: input.oui,

    // }, {
    //   where: {
    //     SN: input.SN,
    //     // state: 'working',
    //   },
    // });
    const result = await this.ctx.model.OnuList.updateOne({sn:input.SN},{$set:{
      mac: input.mac,
      version: input.hardwareVersion, // 终端型号
      manurfactor: input.manurfactor, // 终端厂商
      oui: input.oui,
    }})
    return result;
  }

  async getAllOnus(tid) {
    const result = await this.ctx.model.OnuList.find({tid:tid});
    return result;
  }

  async findOltType(data){
    return new Promise(async(resolve,reject)=>{
      let oltInformation = await this.ctx.model.Olt.findOne({_id:data.oltId})
      let onuInfo = await this.ctx.model.OnuList.findOne({sn:data.SN})
      data.onlyIndex = onuInfo.onlyindex
      const options = new ConnectOption(oltInformation.oltIP, oltInformation.initCommunity, oltInformation.snmpUDPPort, 162, true, true, oltInformation.telnetTCPPort, oltInformation.oltManagementPassword, oltInformation.oltTelnetUsername, oltInformation.oltTelnetPassword, oltInformation.systemName, oltInformation.RZUsername, oltInformation.RZPassword);
     try{
      switch (oltInformation.oltType) {
        case 'ZTE': {
           let zte = new ZTEOLT(options)  
          await zte.changeOnuName(data,this,oltInformation.oltHardVersion)
           break;
        }
        case 'HUAWEI': {
          let hw = new HWOLT(options)
     
          
         await hw.changeOnuName(data,this)
          break;
        }
        default:
         
          break;
      }
       resolve(data.onlyIndex)
     }catch(err){
       console.log('errorHUAWEI')
      reject(err)
     }  
    })
    
  }
  async updateAllOnus(params) {
    const tid = params.tid;
    const result = {
      code: '',
      msg: 'success',
      id: '',
    };
    try {
      await this.ctx.model.OnuList.updateMany({tid,sn:{$in:params.onus}},{$set:{acsSupport: false}})
      await this.ctx.model.OnuList.updateMany({tid,sn:{$in:params.tr069onus}},{$set:{acsSupport:true}})
      //   acsSupport: true,
      // }, { where: {
      //   tid,
      //   sn: {
      //     [Op.in]: params.onus,
      //   },
      // } 
    } catch (error) {
      result.msg = error;
    }
    return result;
  }
}

module.exports = Tr069Service;
